package com.cyy.partner.controller;

import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cyy.partner.pojo.Chat;
import com.cyy.partner.pojo.User;
import com.cyy.partner.service.ChatService;
import com.cyy.partner.service.UserService;
import com.cyy.partner.utils.ThreadLocalUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: cyy
 * @Date: 2024/5/5
 */
@ApiIgnore
@Slf4j
@Component
@ServerEndpoint("/websocket/{username}/{activityId}")
public class WebSocket {
    //当前在线客户端数量（线程安全的）
    private static AtomicInteger onlineClientNumber = new AtomicInteger(0);

    // 当前在线客户端集合（线程安全的）：以键值对方式存储，key是连接的编号，value是连接的对象
    private static Map<String, Session> onlineClientMap = new ConcurrentHashMap<>();

    private static ChatService chatService;
    private static UserService userService;

    public static void setChatService(ChatService chatService){
        WebSocket.chatService = chatService;
    }
    public static void setUserService(UserService userService){
        WebSocket.userService = userService;
    }
    /**
     * 客户端与服务端连接成功
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username, @PathParam("activityId")Long activityId){
        System.out.println("连接上了");
        onlineClientNumber.incrementAndGet();
        //该session已存在，移除
        if(onlineClientMap.containsKey(session.getId())){
            onlineClientMap.remove(session.getId());
        }
        onlineClientMap.put(session.getId(), session);
        log.info("时间[{}]：与用户[{}]的连接成功，当前连接编号[{}]，当前连接总数[{}]",
                new Date().toLocaleString(),
                username,
                session.getId(),
                onlineClientNumber);
        //查询数据
        LambdaQueryWrapper<Chat> chatLambdaQueryWrapper = new LambdaQueryWrapper<>();
        chatLambdaQueryWrapper.eq(Chat::getActivityId, activityId);
        chatLambdaQueryWrapper.orderByAsc(Chat::getTime);
        List<Chat> lists = chatService.list(chatLambdaQueryWrapper);

        for (Chat list :lists) {
            synchronized (session){
                String user = list.getUsername();
                //根据用户名查询到用户的个人信息
                LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>();
                queryWrapper.eq(User::getUsername, user);
                User user1 = userService.getOne(queryWrapper);
                //更新聊天记录中的头像
                list.setUserAvatar(user1.getPhoto());
                chatService.updateById(list);
                //发送信息
                String jsonStr = JSONUtil.toJsonStr(list);
                session.getAsyncRemote().sendText(jsonStr);
            }
        }
    }

    /**
     * 断开连接
     * @param session
     */
    @OnClose
    public void  onClose(Session session, @PathParam("username") String username){
        System.out.println("断开了");
        onlineClientNumber.decrementAndGet();//在线数-1
        onlineClientMap.remove(session.getId());//移除当前连接的session
        log.info("时间[{}]：与用户[{}]的连接关闭，当前连接编号[{}]，当前连接总数[{}]",
                new Date().toLocaleString(),
                username,
                session.getId(),
                onlineClientNumber);
    }

    /**
     * 客户端与服务端连接异常
     * @param error
     * @param session
     */
    @OnError
    public void onError(Throwable error, Session session){
        System.out.println(error.toString());
        System.out.println("有错误");
    }

    /**
     * 客户端向服务端发送消息
     * @param session
     * @param message
     */
    @OnMessage
    public void onMsg(Session session, String message){
        System.out.println(message);
        Chat chat = JSONUtil.toBean(message, Chat.class);
        System.out.println(chat);
        chatService.save(chat);
        sendAllMessage(message);
//        System.out.println("信息来了");
    }

    private void sendAllMessage(String message){
        Set<String> sessionIdSet = onlineClientMap.keySet();
        for (String sessionId :sessionIdSet) {
            Session session = onlineClientMap.get(sessionId);
            synchronized (session){
                session.getAsyncRemote().sendText(message);
            }
        }

    }
}
